/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved.
 */

package logger

import (
	"fmt"
	"os"
	"runtime"
	"strconv"
	"strings"

	"github.com/astaxie/beego/logs"
)

func init() {
	fileName := "/var/log/prim/server.log"
	fileLogConfig := fmt.Sprintf(`{"filename":"%s","level":%d, "perm":"0600"}`, fileName, logs.LevelInfo)
	logs.SetLogger("file", fileLogConfig) // fileLogConfig内容请参考beego fileLogWriter
	logs.EnableFuncCallDepth(false)
	logs.SetPrefix(fmt.Sprintf("(%d)", os.Getpid()))
	logs.GetLogger("HTTP").SetOutput(os.Stdout)
}

// Debug formats according to a format specifier and writes debug log to specified log file
func Debug(format string, args ...interface{}) {
	format = getFunctionCallInfo() + format
	logs.GetBeeLogger().Debug(format, args...)
}

// Info formats according to a format specifier and writes info log to specified log file
func Info(format string, args ...interface{}) {
	format = getFunctionCallInfo() + format
	logs.GetBeeLogger().Info(format, args...)
}

// Warnf formats according to a format specifier and writes warn log to specified log file
func Warn(format string, args ...interface{}) {
	format = getFunctionCallInfo() + format
	logs.GetBeeLogger().Warn(format, args...)
}

// Error formats according to a format specifier and writes error log to specified log file
func Error(format string, args ...interface{}) {
	format = getFunctionCallInfo() + format
	logs.GetBeeLogger().Error(format, args...)
}

type Logger struct {
	taskName  string
	beeLogger *logs.BeeLogger
}

// NewLogger sets task name to runtime log
func NewLogger(taskName string) *Logger {
	return &Logger{
		taskName:  taskName,
		beeLogger: logs.GetBeeLogger(),
	}
}

// Debug formats according to a format specifier and writes debug log to specified log file
func (l *Logger) Debug(format string, args ...interface{}) {
	format = getFunctionCallInfo() + "[" + l.taskName + "]  " + format
	logs.GetBeeLogger().Debug(format, args...)
}

// Info formats according to a format specifier and writes info log to specified log file
func (l *Logger) Info(format string, args ...interface{}) {
	format = getFunctionCallInfo() + "[" + l.taskName + "]  " + format
	logs.GetBeeLogger().Info(format, args...)
}

// Warnf formats according to a format specifier and writes warn log to specified log file
func (l *Logger) Warn(format string, args ...interface{}) {
	format = getFunctionCallInfo() + "[" + l.taskName + "]  " + format
	logs.GetBeeLogger().Warn(format, args...)
}

// Error formats according to a format specifier and writes error log to specified log file
func (l *Logger) Error(format string, args ...interface{}) {
	format = getFunctionCallInfo() + "[" + l.taskName + "]  " + format
	logs.GetBeeLogger().Error(format, args...)
}

func getFunctionCallInfo() string {
	_, file, line, ok := runtime.Caller(2)
	if !ok {
		file = "???"
		line = 0
	} else {
		index := strings.LastIndex(file, "src")
		if index >= 0 {
			file = file[index:]
		}
	}

	return "[" + file + ":" + strconv.Itoa(line) + "]  "
}
